docxtemplater实现纯前端导出word 您所在的位置:网站首页 Image Module docxtemplater实现纯前端导出word

docxtemplater实现纯前端导出word

2023-10-30 01:39| 来源: 网络整理| 查看: 265

最近做了一个纯前端导出word的功能,记录下实现过程和遇到的坑

1.下载需要的依赖

npm install docxtemplater pizzip jszip-utils file-saver docxtemplater-image-module-free

2.util文件夹下创建doc.js文件

doc.js

import docxtemplater from 'docxtemplater' import PizZip from 'pizzip' import JSZipUtils from 'jszip-utils' import { saveAs } from 'file-saver' import ImageModule from "docxtemplater-image-module-free"; /** 导出docx @param { String } tempDocxPath 模板文件路径 @param { Object } data 文件中传入的数据 @param { String } fileName 导出文件名称 */ export const exportDocx = (tempDocxPath, data, fileName) => { // 读取并获得模板文件的二进制内容 JSZipUtils.getBinaryContent(tempDocxPath, (error, content) => { // input.docx是模板。我们在导出的时候,会根据此模板来导出对应的数据 // 抛出异常 if (error) { throw error } let opts = {}; opts.centered = false; opts.getImage = function (tagValue) { return new Promise(function (resolve, reject) { JSZipUtils.getBinaryContent(tagValue, function (error, content) { if (error) { return reject(error); } return resolve(content); }); }); }; //图片有关代码,没有图片的可以删除 opts.getSize = (img, tagValue, tagName) => { return [200, 105]; //图片大小 (固定的) // 非固定(这里是设置宽度最大为300px的图片) // return new Promise(function (resolve, reject) { // let image = new Image(); // image.src = tagValue; // let imgWidth, imgHeight, scale; // image.onload = function () { // imgWidth = image.width; // imgHeight = image.height; // scale = 0; // if (imgWidth > 300) { // scale = 300 / imgWidth; // imgWidth = 300; // imgHeight = imgHeight * scale; // } // resolve([imgWidth, imgHeight]); // }; // image.onerror = function (e) { // console.log("img, tagValue, tagName : ", img, tagValue, tagName); // reject(e); // }; // }); }; let imageModule = new ImageModule(opts); // 创建一个JSZip实例,内容为模板的内容 const zip = new PizZip(content) // 创建并加载docxtemplater实例对象 const doc = new docxtemplater().loadZip(zip).attachModule(imageModule).compile(); doc.resolveData({ ...data.form }).then(() => { doc.render() const out = doc.getZip().generate({ type: 'blob', mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' }) // Output the document using Data-URI saveAs(out, fileName) }).catch(err => console.log('errorsss', err)) }) }

3.创建.docx文档,示例:

注意: 这个.docx模板放在public文件夹里

image.png

word表格里面写的编码的含义:

{xxx} 直接渲染数据的xxx字段 {#xxx}{/xxx} 循环数组数据 {%xxx} 渲染图片

4.要求后端返回数据格式如下:

const data = { title: "工作日报", officeName: '', options: [{index:1, name:'测试数据', number: 1, remark:'这是一条备注信息'}], //存放表格数据 filler: '', filledTime: '', imgList: [{ img: 'https://img-s-msn-com.akamaized.net/tenant/amp/entityid/AA17ORRg.img?w=640&h=336&m=6' },{ img: 'https://images.pexels.com/photos/3291250/pexels-photo-3291250.jpeg?auto=compress&cs=tinysrgb&w=1600&lazy=load' }] //图片数据 }

5.调用方法导出word

import { exportDocx } from '@/utils/doc.js' const exportWord = () => { const data = { form: data } exportDocx('/template.docx', data, `${deta.title}.docx`) }

成果:

image.png

遇到的坑:

.docx文件一定要自己创建,不要找其他模板改,会报错 线上的图片路径不存在时,会无法导出,解决方法如下: public文件夹下static文件夹放入‘图片不存在’的png图片,线上图片不存在就加载‘图片不存在的图片’ 判断线上图片是否存在的方法: const checkImgExists = (imgurl) => { return new Promise(function (resolve, reject) { var ImgObj = new Image(); ImgObj.src = imgurl; ImgObj.onload = function () { resolve(imgurl); }; ImgObj.onerror = function (err) { reject("/static/img/failImg.png"); }; }); } //imageList,后端返回的数组图片数据 imageList.map(async (item) => { const res = await this.checkImgExists(item); return { img: res, }; }); Promise.all(newImgList).then((res) => { data.imgList = res })

3.导出的图片默认竖着排列,想横着排,官网有个grid布局用了却报错,暂未解决

image.png



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有